package com.qf.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.qf.feign.OrderServiceFeign;
import com.qf.pojo.R;
import com.qf.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.concurrent.atomic.AtomicInteger;

@RestController
@RequestMapping("/user")
@DefaultProperties(defaultFallback = "defaultFallback")
public class UserController2 {

    @Autowired
    UserService userService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private OrderServiceFeign orderServiceFeign;

    /**
     * 默认降级方法. 要求返回值必须和目标受保护方法一致，参数列表为空
     *  在保证参数列表为空的前提下，可以接收一个异常对象(可选)
     * @return
     */
    public R defaultFallback(Throwable e){
        e.printStackTrace();

        //返回降级数据
        return R.error().putMsg("default 服务器忙，稍后重试~~");
    }


    /**
     * 降级方法在定义时，参数列表和返回值必须要和目标受保护的方法保持一致
     *  在其他参数保持一致的基础之上，我们可以在参数列表中接收一个异常对象（可选）
     * @param id
     * @return
     */
    public R fallbackMethod(Integer id,Throwable e){
        //打印异常
        e.printStackTrace();

        return R.error().putMsg("服务器忙，稍后重试~~");
    }

    @GetMapping("/{id}")
    //在需要实现保护的资源上开启服务保护功能
    //@HystrixCommand(fallbackMethod = "fallbackMethod")
    /*@HystrixCommand(
            //配置hystrix的线程池参数(同一时间，只能接收5个请求访问，来更多的请求访问，直接走降级失败)
            //coreSize配置的是 核心线程数和最大线程数
            threadPoolProperties = {@HystrixProperty(name = "coreSize",value = "5")},
            commandProperties = {
                    //设置服务保护过程中的调用超时时间（默认是1s，设置的是7s）
                    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "7000"),

                    *//*
                        以下三个参数结合在一起的含义是：
                            10s内，统计请求数量是否最少达到了4个，其中最少有50%的请求出现问题
                                如果是：触发熔断，熔断器的开关为open状态，所有的后续请求都直接降级
                                如果否：正常访问
                     *//*
                    //触发熔断的请求数量阈值（默认是20个，设置为4个）
                    @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "4"),
                    //设置熔断统计时间窗的值（默认是5s，设置10s）
                    @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),
                    //设置触发熔断的错误概率(默认就是50%)
                    @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),
            }
    )*/
    @HystrixCommand
    public R findOrders(@PathVariable("id") Integer id) throws InterruptedException {

        Thread.sleep(5000);

        if (id == 1){
            throw  new RuntimeException("error...");
        }

        //R r = restTemplate.getForObject("http://QF-ORDER/order/" + id, R.class);
        R r = orderServiceFeign.findByUid(id);
        return r;
    }
}
